package com.rfid.uhf288.controller;

import com.alibaba.fastjson.JSONObject;
import com.rfid.uhf288.Device;
import com.rfid.uhf288.JsonResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@RestController
public class DeviceController {
    static {
        System.loadLibrary("com_rfid_uhf288_Device");
    }

    @ApiOperation(value = "连接指定串口", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "port", value = "与读写器连接的串口号。1-COM1;2-COM2…", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "comAddr", value = "输入读写器地址，如果在不清楚真实地址的情况下，可以输入广播地址0xFF，函数调用成功后，此参数将返回真实地址。", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "baud", value = "串口通讯波特率。0-9600；1-19200；2-38400；5-57600；6-115200。", dataType = "int", required = true, paramType = "form"),
    })

    @RequestMapping(value = "/openComPort", method = RequestMethod.POST)
    public JSONObject openComPort(@RequestParam int port, @RequestParam int comAddr, @RequestParam byte baud) {
        byte[] comAddr1 = new byte[1];
        comAddr1[0] = (byte) comAddr;

        Device reader = new Device();
        int[] PortHandle = new int[1];

        //串口连接
        int result = reader.OpenComPort(port, comAddr1, baud, PortHandle);

        if (result == 0) {
            Map<String, Object> map = new HashMap<>();
            map.put("PortHandle", PortHandle[0]);
            map.put("ComAdr", comAddr1[0]);
            return JsonResult.success(map);
        }

        return JsonResult.fail("失败:" + result);
    }

    @ApiOperation(value = "关闭指定串口", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "portHandle", value = "与读写器连接的句柄，打开串口API获得的句柄。 ", dataType = "int", required = true, paramType = "form"),
    })

    @RequestMapping(value = "/closeSpecComPort", method = RequestMethod.POST)
    public JSONObject closeSpecComPort(@RequestParam int portHandle) {
        Device reader = new Device();
        int result = reader.CloseSpecComPort(portHandle);

        if (result == 0) {
            return JsonResult.success("关闭成功");
        }

        return JsonResult.fail("失败:" + result);
    }

    @ApiOperation(value = "打开TCP连接", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "port", value = "与读写器连接的端口号", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "iPaddr", value = "读写器的IP地址", dataType = "string", required = true, paramType = "form"),
            @ApiImplicitParam(name = "comAdr", value = "输入读写器地址，对于TCP连接，可直接输入广播地址255", dataType = "int", required = true, paramType = "form"),
    })

    @RequestMapping(value = "/openNetPort", method = RequestMethod.POST)
    public JSONObject openNetPort(@RequestParam int port, @RequestParam String iPaddr, @RequestParam byte comAdr) {
        Device reader = new Device();

        byte[] comAddr = new byte[1];
        comAddr[0] = comAdr;

        int[] PortHandle = new int[1];

        int result = reader.OpenNetPort(port, iPaddr, comAddr, PortHandle);

        if (result == 0) {
            return JsonResult.success(PortHandle[0]);
        }

        return JsonResult.fail("失败:" + result);
    }

    @ApiOperation(value = "关闭TCP连接", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "portHandle", value = "与读写器连接的句柄，打开串口API获得的句柄。 ", dataType = "int", required = true, paramType = "form"),
    })

    @RequestMapping(value = "/closeNetPort", method = RequestMethod.POST)
    public JSONObject closeNetPort(@RequestParam int portHandle) {
        Device reader = new Device();

        int result = reader.CloseNetPort(portHandle);

        if (result == 0) {
            return JsonResult.success("关闭成功");
        }

        return JsonResult.fail("失败:" + result);
    }

    @ApiOperation(value = "获取读写器信息", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "portHandle", value = "连接读写器返回的句柄。", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "comAddr", value = "使用连接读写器返回的读写器地址", dataType = "int", required = true, paramType = "form"),
    })

    @RequestMapping(value = "/getReaderInformation", method = RequestMethod.POST)
    public JSONObject getReaderInformation(@RequestParam int portHandle, @RequestParam byte comAddr) {
        Device reader = new Device();

        byte[] versionInfo = new byte[2];
        byte[] readerType = new byte[1];
        byte[] trType = new byte[1];
        byte[] dmaxfre = new byte[1];
        byte[] dminfre = new byte[1];
        byte[] powerdBm = new byte[1];
        byte[] InventoryScanTime = new byte[1];
        byte[] Ant = new byte[1];
        byte[] BeepEn = new byte[1];
        byte[] OutputRep = new byte[1];
        byte[] CheckAnt = new byte[1];

        byte[] comAddr1 = new byte[1];
        comAddr1[0] = comAddr;
        int result = reader.GetReaderInformation(comAddr1, versionInfo, readerType, trType, dmaxfre, dminfre, powerdBm, InventoryScanTime,
                Ant, BeepEn, OutputRep, CheckAnt, portHandle);

        if (result == 0) {
            Map<String, Object> map = new HashMap<>();
            map.put("comAddr", comAddr1[0]);
            map.put("versionInfo", versionInfo[0] + "." + versionInfo[1]);
            map.put("ant", Ant[0]);
            map.put("dminfre", dminfre[0]);
            map.put("dmaxfre", dmaxfre[0]);
            map.put("readerType", readerType[0]);
            map.put("powerdBm", powerdBm[0]);
            map.put("ScanTime", InventoryScanTime[0]);
            return JsonResult.success(map);
        }

        return JsonResult.fail("失败:");
    }

    @ApiOperation(value = "设置读写器地址", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "portHandle", value = "连接读写器返回的句柄", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "comAddr", value = "使用连接读写器返回的读写器地址", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "comAdrData", value = "1个字节，要修改的新地址", dataType = "int", required = true, paramType = "form"),
    })

    @RequestMapping(value = "/setAddress", method = RequestMethod.POST)
    public JSONObject setAddress(@RequestParam int portHandle, @RequestParam byte comAddr, @RequestParam byte comAdrData) {
        Device reader = new Device();

        byte[] comAddr1 = new byte[1];
        comAddr1[0] = comAddr;

        int result = reader.SetAddress(comAddr1, comAdrData, portHandle);

        if (result == 0) {
            return JsonResult.success("设置成功");
        }

        return JsonResult.fail("失败:" + result);
    }

    @ApiOperation(value = "询查命令", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "comAddr", value = "", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "qValue", value = "", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "session", value = "", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "maskMem", value = "", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "maskLen", value = "", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "maskData", value = "", dataType = "string", required = true, paramType = "form"),
            @ApiImplicitParam(name = "maskFlag", value = "", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "adrTID", value = "", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "lenTID", value = "", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "tIDFlag", value = "", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "target", value = "", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "inAnt", value = "", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "scantime", value = "", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "fastFlag", value = "", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "portHandle", value = "", dataType = "int", required = true, paramType = "form"),
    })

    @RequestMapping(value = "/inventory_G2", method = RequestMethod.POST)
    public JSONObject inventory_G2(@RequestParam byte comAddr, @RequestParam byte qValue,
                                   @RequestParam byte session, @RequestParam byte maskMem,
                                   @RequestParam byte maskLen, @RequestParam String maskData, @RequestParam byte maskFlag,
                                   @RequestParam byte adrTID, @RequestParam byte lenTID,
                                   @RequestParam byte tIDFlag, @RequestParam byte target, @RequestParam byte inAnt,
                                   @RequestParam byte scantime, @RequestParam byte fastFlag,
                                   @RequestParam int portHandle) {
        Device reader = new Device();

        byte[] MaskAdr = new byte[2];
        // byte[] MaskData = new byte[256];
        byte[] MaskData = maskData.getBytes();
        byte InAnt = (byte) 0x80;
        byte[] pEPCList = new byte[20000];
        int[] Totallen = new int[1];
        int[] CardNum = new int[1];

        byte[] Ant = new byte[1];

        byte[] ComAddr = new byte[1];
        ComAddr[0] = comAddr;

        int result = reader.Inventory_G2(ComAddr, qValue, session, maskMem, MaskAdr, maskLen, MaskData, maskFlag,
                adrTID, lenTID, tIDFlag, target, InAnt, scantime, fastFlag, pEPCList, Ant, Totallen,
                CardNum, portHandle);

        if (result == 0) {
            Map<String, Object> map = new HashMap<>();
            map.put("CardNum", CardNum[0]);
        }

        return JsonResult.fail("失败:" + result);
    }

    @ApiOperation(value = "读数据", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "comAddr", value = "使用连接读写器返回的读写器地址", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "EPC", value = "ENum个字，标签的EPC号", dataType = "string", required = true, paramType = "form"),
            @ApiImplicitParam(name = "ENum", value = "1个字节，标签的EPC号字长度，当Enum=255时，使用掩码方式", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "Mem", value = "1个字节，选择要读取的存储区", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "WordPtr", value = "1个字节，要读取的起始字地址", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "Num", value = "1个字节，要读取的字长度", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "Password", value = "4个字节，标签的访问密码", dataType = "string", required = true, paramType = "form"),
            @ApiImplicitParam(name = "MaskMem", value = "1个字节，掩码区", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "MaskAdr", value = "2个字节，掩码的起始位地址（单位：Bits）。范围0~16383", dataType = "string", required = true, paramType = "form"),
            @ApiImplicitParam(name = "MaskLen", value = "1个字节，掩码的位长度（单位：Bits）", dataType = "string", required = true, paramType = "form"),
            @ApiImplicitParam(name = "MaskData", value = "n个字节，掩码数据。n等于MaskLen/8。如果MaskLen不是8的整数倍，则n为[MaskLen/8]取整再加1。不够的在低位补0", dataType = "string", required = true, paramType = "form"),
    })

    @RequestMapping(value = "/readData_G2", method = RequestMethod.POST)
    public JSONObject readData_G2(@RequestParam int comAddr, @RequestParam String EPC, @RequestParam int ENum, @RequestParam int Mem,
                                  @RequestParam int WordPtr, @RequestParam int Num, @RequestParam String Password, @RequestParam int MaskMem,
                                  @RequestParam String MaskAdr, @RequestParam int MaskLen, @RequestParam String MaskData) {
        Device reader = new Device();

        byte[] comAddr1 = new byte[1];
        comAddr1[0] = (byte) comAddr;

        byte[] epc = EPC.getBytes();

        byte[] Data = new byte[Num];

        int[] Errorcode = new int[1];

        int PortHandle = 0;

        int result = reader.ReadData_G2(comAddr1, epc, (byte) ENum, (byte) Mem, (byte) WordPtr, (byte) Num, Password.getBytes(),
                (byte) MaskMem, MaskAdr.getBytes(), (byte) MaskLen, MaskData.getBytes(), Data, Errorcode, PortHandle);

        if (result == 0) {
            Map<String, Object> map = new HashMap<>();
            map.put("Data", Data);
            map.put("ErrorCode", Errorcode);
            map.put("PortHandle", PortHandle);

            return JsonResult.success(map);
        }

        return JsonResult.fail("失败:" + result);
    }

    @ApiOperation(value = "工作频率设置", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "comAddr", value = "使用连接读写器返回的读写器地址", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "dmaxfre", value = "1个字节，Bit7-Bit6用于频段设置用；Bit5-Bit0表示当前读写器工作的最大频点", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "dminfre", value = "1个字节，Bit7-Bit6用于频段设置用；Bit5-Bit0表示当前读写器工作的最小频点", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "PortHandle", value = "连接读写器返回的句柄", dataType = "int", required = true, paramType = "form"),
    })

    @RequestMapping(value = "/setRegion", method = RequestMethod.POST)
    public JSONObject setRegion(@RequestParam byte comAddr, @RequestParam byte dmaxfre, @RequestParam byte dminfre, @RequestParam int PortHandle) {
        Device reader = new Device();

        byte[] ComAddr = new byte[1];
        ComAddr[0] = comAddr;

        int result = reader.SetRegion(ComAddr, dmaxfre, dminfre, PortHandle);

        if (result == 0) {
            return JsonResult.success("设置成功");
        }

        return JsonResult.fail("失败:" + result);
    }

    @ApiOperation(value = "工作模式设置", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "comAddr", value = "使用连接读写器返回的读写器地址", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "readMode", value = "1个字节，工作模式", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "PortHandle", value = "连接读写器返回的句柄", dataType = "int", required = true, paramType = "form"),
    })

    @RequestMapping(value = "/setWorkMode", method = RequestMethod.POST)
    public JSONObject setWorkMode(@RequestParam byte comAddr, @RequestParam byte readMode, @RequestParam int PortHandle) {
        Device reader = new Device();

        byte[] ComAddr = new byte[1];
        ComAddr[0] = comAddr;

        byte readMode1 = readMode;
        int result = reader.SetWorkMode(ComAddr, readMode1, PortHandle);

        if (result == 0) {
            return JsonResult.success("设置成功");
        }

        return JsonResult.fail("失败:" + result);
    }

    @ApiOperation(value = "天线配置", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "comAddr", value = "使用连接读写器返回的读写器地址", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "ant", value = "1个字节，天线配置信息。天线至少要配置一个", dataType = "int", required = true, paramType = "form"),
            @ApiImplicitParam(name = "PortHandle", value = "连接读写器返回的句柄", dataType = "int", required = true, paramType = "form"),
    })

    @RequestMapping(value = "/setAntennaMultiplexing", method = RequestMethod.POST)
    public JSONObject setAntennaMultiplexing(@RequestParam byte comAddr, @RequestParam byte ant, @RequestParam int PortHandle) {
        Device reader = new Device();

        byte[] ComAddr = new byte[1];
        ComAddr[0] = comAddr;

        int result = reader.SetAntennaMultiplexing(ComAddr, ant, PortHandle);

        if (result == 0) {
            return JsonResult.success("设置成功");
        }

        return JsonResult.fail("失败:" + result);
    }
}
